package com.py.credit.service.impl;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.stream.Collectors;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;

import org.apache.commons.collections4.ListUtils;
import org.apache.cxf.configuration.jsse.TLSClientParameters;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
import org.apache.cxf.transport.http.HTTPConduit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.py.credit.dao.UploadXycnDao;
import com.py.credit.entity.FrPromiseEntity;
import com.py.credit.entity.SubmitLogsDetails;
import com.py.credit.entity.SubmitLogsInfo;
import com.py.credit.entity.SubmitRespBean;
import com.py.credit.entity.SubmitXycnReqData;
import com.py.credit.entity.SubmitXycnRespData;
import com.py.credit.entity.SubmitXzxkRespData;
import com.py.credit.entity.ZrrPromiseEntity;
import com.py.credit.service.UploadXycnService;
import com.py.credit.utils.DateUtil;

import com.py.credit.utils.SubmitConvXmlUtils;

@Service
public class UploadXycnServiceImpl implements UploadXycnService {
    private final Logger log = LoggerFactory.getLogger(UploadXycnServiceImpl.class);
    
    @Autowired
    private UploadXycnDao uploadXycnDao;

	@Override
    public String execute(String apiKey,int type,String namespace, String postUrl, String method) {
        try {
            String tableName="";
            if(type==1){
                tableName="t_1000000010566_3pv3rusuzb";
                List<FrPromiseEntity> promiseBookList = uploadXycnDao.getFrPromiseBookLlist();

                List<List<FrPromiseEntity>> parList = ListUtils.partition(promiseBookList, 999);

                for (int i = 0; i < parList.size(); i++) {
                    List<FrPromiseEntity> spList = parList.get(i);
                    SubmitXycnReqData req = new SubmitXycnReqData();
                    req.setFrPromise(spList);
                    // 上报数据转换成xml
                    String frcnsXmlValue = SubmitConvXmlUtils.convert2Xml(req);
                    System.out.println("上报法人承诺书转换成xml" + frcnsXmlValue);
                    log.debug("法人承诺书XML内容：{}", frcnsXmlValue);
                    String respXzxkValue = doPostSoap1_1(postUrl, frcnsXmlValue,apiKey, method);

                    log.info("返回法人承诺书上报结果信息：{}", respXzxkValue);
                    System.out.println("返回法人承诺书上报结果信息：{}" + respXzxkValue);
                    SubmitXycnRespData frResp = (SubmitXycnRespData) SubmitConvXmlUtils
                            .convertXml2Object(SubmitXycnRespData.class, respXzxkValue);
                    List<String> recordIds = spList.stream().map(FrPromiseEntity -> FrPromiseEntity.getUUID()).collect(Collectors.toList());
                    
//                    保存返回数据
                    this.savePromiseSubmitLogs(type, frResp.getResp(),recordIds,tableName);
                }
            }else if(type==2){
                tableName="t_1000010010567_jvhob4c2lb";
                List<ZrrPromiseEntity> promiseBookList = uploadXycnDao.getZrrPromiseBookLlist();

                List<List<ZrrPromiseEntity>> parList = ListUtils.partition(promiseBookList, 999);

                for (int i = 0; i < parList.size(); i++) {
                    List<ZrrPromiseEntity> spList = parList.get(i);
                    SubmitXycnReqData req = new SubmitXycnReqData();
                    req.setZrrPromise(spList);
                    // 上报数据转换成xml
                    String frcnsXmlValue = SubmitConvXmlUtils.convert2Xml(req);
                    System.out.println("上报自然人承诺书转换成xml" + frcnsXmlValue);
                    log.debug("自然人承诺书XML内容：{}", frcnsXmlValue);
                    String respXzxkValue = doPostSoap1_1(postUrl, frcnsXmlValue,apiKey, method);

                    log.info("返回自然人承诺书上报结果信息：{}", respXzxkValue);
                    System.out.println("返回行自然人承诺书结果信息：{}" + respXzxkValue);
                    SubmitXycnRespData zrrResp = (SubmitXycnRespData) SubmitConvXmlUtils
                            .convertXml2Object(SubmitXycnRespData.class, respXzxkValue);
                    List<String> recordIds = spList.stream().map(ZrrPromiseEntity -> ZrrPromiseEntity.getUUID()).collect(Collectors.toList());
                    
//                    保存返回数据
                    this.savePromiseSubmitLogs(type, zrrResp.getResp(),recordIds,tableName);
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
            log.info("上传数据失败:", e.getMessage());
        }
        return null;
    }

    /**
     * 使用SOAP1.1发送消息
     *
     * @param postUrl
     * @param soapXml
     * @param soapAction
     * @return
     */
    public String doPostSoap1_1(String postUrl, String soapXml, String apiKey,
                                String soapAction) throws UnsupportedEncodingException {

//    	javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier(
//
//    			new javax.net.ssl.HostnameVerifier(){
//
//    			public boolean verify(String hostname,
//
//    			javax.net.ssl.SSLSession sslSession) {
//    			return true;
//
//
//    			}
//
//    			});
//
//    			System.clearProperty("javax.net.ssl.trustStore");
//
//    			System.clearProperty("javax.net.ssl.trustStorePassword");
//
//    			try {
//
//    			//这里需要注意的是证书路径如果有空格，上面getPath()会把空格转码为%20F，需要转一次码，其他特殊字符也需注意
//    		    	  System.setProperty("javax.net.ssl.trustStore", "C:\\cacerts");
//    		    	  System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
//    		    	  System.setProperty("org.jboss.security.ignoreHttpsHost", "true");
//    			} catch (Exception e) {
//
//    			e.printStackTrace();
//
//    			}
    	try {
			trustAllHttpsCertificates();
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
    	HttpsURLConnection.setDefaultHostnameVerifier(hv);
        try {
        	 Properties props = System.getProperties();
             props.setProperty("org.apache.cxf.stax.allowInsecureParser", "1");
             props.setProperty("UseSunHttpHandler", "true");
             props.setProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");;
             String nameSpace = "http://dal.rjcloud.dal";
             TLSClientParameters tlsParams = new TLSClientParameters();
 			tlsParams.setDisableCNCheck(true);
 			
             JaxWsDynamicClientFactory clientFactory = JaxWsDynamicClientFactory.newInstance();
             Client client = clientFactory.createClient(postUrl);
             HTTPConduit httpConduit = (HTTPConduit) client.getConduit();
 			httpConduit.setTlsClientParameters(tlsParams);
             System.out.println("请求地址:"+postUrl);
             System.out.println("请求方法:"+soapAction);
             Object[] obj = client.invoke(soapAction, new Object[]{apiKey,soapXml});
             System.out.println("请求结果:");
             System.out.println(String.valueOf(obj[0]));
             return String.valueOf(obj[0]);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println(e.getMessage());
        }
    return "";
    }
    /**
    *
    * @param type type
    * @param respList 返回值
    * @param xzxkList 许可集合
    * @param xzcfList 处罚集合
    * @param tableName 表名
    */
   @Transactional
    void savePromiseSubmitLogs(int type, List<SubmitRespBean> respList, List<String> recordIds,String tableName) {
       // 保存上报记录信息及明细信息
       DateUtil dataUtil = DateUtil.getInstance();
       String batNo = "BN" + dataUtil.getCurrDate(DateUtil.YYYYMMDDHHMMSS);
       String subDate = dataUtil.getCurrDate(DateUtil.YYYY_MM_DD);
       SubmitLogsInfo logsInfo = new SubmitLogsInfo();

       int respSize = respList.size();
       SubmitLogsDetails detail = null;
       ArrayList<SubmitLogsDetails> detList = new ArrayList<SubmitLogsDetails>();
       //原数据的recordIds 集合
    
  
         
           for (int i = 0; i < respSize; i++) {
               SubmitRespBean reps = respList.get(i);
               if (reps != null && reps.getLine() != null) {
          
                   detail = new SubmitLogsDetails();
                   detail.setBatNo(batNo);
                   detail.setSubCode(reps.getCode());
                   detail.setSubMsg(reps.getMsg());
                   detail.setRelId(recordIds.get(Integer.valueOf(reps.getLine())-1));
       
                   detail.setRecStatus("1");
                   detList.add(detail);
               } else {
                   logsInfo.setRemarkInfo(reps.getCode() + ":" + reps.getMsg());
               }
           }

       //
       ArrayList<SubmitRespBean> sucList = (ArrayList<SubmitRespBean>) respList.stream()
               .filter((SubmitRespBean resp) -> "00".equals(resp.getCode())).collect(Collectors.toList());

       uploadXycnDao.updateXzStatusByRecordIds(tableName,recordIds);//需改原数据的状态
       int sucSize = sucList.size();// 成功条数

       logsInfo.setBatNo(batNo);
       logsInfo.setType(type);
       logsInfo.setSubDate(subDate);
       logsInfo.setSuccNum("" + sucSize);
       logsInfo.setFailNum("" + (respList.size() - sucSize));
       logsInfo.setRecStatus("1");
       uploadXycnDao.saveSubmitLogsInfo(logsInfo);
       // 保存上报数据明细
       if (null == logsInfo.getRemarkInfo() || "".equals(logsInfo.getRemarkInfo())) {
    	   uploadXycnDao.saveSubmitLogsDetails(detList);
       }
   }
   
   HostnameVerifier hv = new HostnameVerifier() {
       public boolean verify(String urlHostName, SSLSession session) {
           System.out.println("Warning: URL Host: " + urlHostName + " vs. "
                              + session.getPeerHost());
           return true;
       }
   };

	private static void trustAllHttpsCertificates() throws Exception {
		javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1];
		javax.net.ssl.TrustManager tm = new miTM();
		trustAllCerts[0] = tm;
		javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext
				.getInstance("SSL");
		sc.init(null, trustAllCerts, null);
		javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc
				.getSocketFactory());
	}

	static class miTM implements javax.net.ssl.TrustManager,
			javax.net.ssl.X509TrustManager {
		public java.security.cert.X509Certificate[] getAcceptedIssuers() {
			return null;
		}

		public boolean isServerTrusted(
				java.security.cert.X509Certificate[] certs) {
			return true;
		}

		public boolean isClientTrusted(
				java.security.cert.X509Certificate[] certs) {
			return true;
		}

		public void checkServerTrusted(
				java.security.cert.X509Certificate[] certs, String authType)
				throws java.security.cert.CertificateException {
			return;
		}

		public void checkClientTrusted(
				java.security.cert.X509Certificate[] certs, String authType)
				throws java.security.cert.CertificateException {
			return;
		}
	}
}
